package com.syni.mdd.sjb.common.gateway.filter;

import com.syni.mdd.sjb.common.gateway.auth.MddUserService;
import com.syni.mdd.sjb.common.gateway.utils.CommonUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpHeaders;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.MultiValueMap;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.List;
import java.util.Map;

@Component
public class GatewayAuthCheckFilter implements GlobalFilter,Ordered {
    private final static String TOKEN_CHECK = "API_0101@MDD_SUCCESS";

    private final static String CHECK_SUCCESS_CODE = "00";

    @Autowired(required = false)
    MddUserService mddUserService;

    private Logger log = LoggerFactory.getLogger(getClass());

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest ctx = exchange.getRequest();
        log.info("request URI data : {}" + ctx.getURI().toString());
        HttpHeaders httpHeaders = ctx.getHeaders();
        try {
            List<String> tokenArray = httpHeaders.get("token");
            if(!CollectionUtils.isEmpty(tokenArray)){
                String token = tokenArray.get(0);
                Map<String,Object> data = mddUserService.checkZuulIntoUser(token);
                if(data.containsKey("status") && CHECK_SUCCESS_CODE.equals(data.get("status").toString())){
                    Map<String,Object> userData = (Map<String, Object>) data.get("data");
                    String checkSecret = CommonUtil.MD5(token + TOKEN_CHECK);
                    ServerHttpRequest req = exchange.getRequest().mutate().headers(header -> {
                        header.add("USER_TOKEN_CHECK",checkSecret);
                        header.add("zuulCheck",CHECK_SUCCESS_CODE);
                        if(userData.containsKey("userid") && CommonUtil.checkNullAndEmpty(userData.get("userid"))) {
                            header.set("userid", userData.get("userid").toString());
                        }
                    }).build();
                    ServerWebExchange webExchange = exchange.mutate().request(req).build();
                    return chain.filter(webExchange);
                }
            }
        }catch (Exception e){
            log.error(e.getMessage(),e);
        }
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return 0;
    }
}
